package com.example.spring.security.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.*;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author : zhayh
 * @date : 2021-4-17 17:42
 * @description : Spring Security配置类
 */

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    PasswordEncoder passwordEncoder() {
        // 指定密码加密方法，加盐哈希
        return new BCryptPasswordEncoder();
    }

    // 基于内存的认证，配置用户及对应的角色
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("root").password(passwordEncoder().encode("123")).roles("admin", "dba")
                .and()
                .withUser("admin").password(passwordEncoder().encode("123")).roles("admin", "user")
                .and()
                .withUser("user").password(passwordEncoder().encode("123")).roles("user");
    }

    // 授权，配置URL访问权限
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests() // 开启HttpSecurity配置
                .antMatchers("/", "/index").permitAll()
                .antMatchers("/admin/**").hasRole("admin")
                .antMatchers("/user/**").access("hasAnyRole('admin', 'user')")
                .antMatchers("/dba/**").access("hasRole('admin') and hasRole('dba')")
                .anyRequest().authenticated()  // 其它请求登录之后都能访问
                .and()
                .formLogin().permitAll() // 登录表单页面的配置
                .and().csrf().disable();  // 关闭防csrf攻击
    }
}
